package com.zk.config.api.factory;

import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.support.PropertiesLoaderSupport;
import org.springframework.util.CollectionUtils;
import com.zk.config.api.client.ConfigClient;

import lombok.Setter;

public class PropertiesFactoryBean  extends PropertiesLoaderSupport
implements FactoryBean<Properties>, InitializingBean {

	@Setter
	private ConfigClient configClient;
	private boolean singleton;
	private Properties singletonInstance;

	public PropertiesFactoryBean() {
		this.singleton = true;
	}
	
	@Override
	public void afterPropertiesSet() throws IOException {
		if (this.singleton)
			this.singletonInstance = createProperties();
	}

	@Override
	public Properties getObject() throws Exception {
		if (this.singleton) {
			return this.singletonInstance;
		}

		return createProperties();
	}

	@Override
	public Class<?> getObjectType() {
		return Properties.class;
	}
	
	public void setSingleton(boolean singleton) {
		this.singleton = singleton;
	}

	@Override
	public boolean isSingleton() {
		return this.singleton;
	}
	
	protected Properties createProperties() throws IOException {
		return mergeProperties();
	}
	
	@Override
	protected Properties mergeProperties() throws IOException {
		Properties result = new Properties();

		if (this.localOverride) {
			loadProperties(result);
		}

		if (this.localProperties != null) {
			for (Properties localProp : this.localProperties) {
				CollectionUtils.mergePropertiesIntoMap(localProp, result);
			}
		}
		
		if (configClient != null) {
			Map<String, Properties> fileProperties = configClient.getZkCache().getFileProperties();
			for(String key:fileProperties.keySet()) {
				Properties zkProperties = fileProperties.get(key);
				CollectionUtils.mergePropertiesIntoMap(zkProperties, result);
			}
		}

		if (!(this.localOverride)) {
			loadProperties(result);
		}

		return result;
	}
}
